/**
 * 常量相关的属性或者方法放在前面,方便修改
 * Created by Administrator on 2017/6/10.
 */
//常量
var COMMON_CONST = {
    TREE_ORG: '{URL_UMS}ums/tree/getOrgTree'  //组织树,含单位和部门
    ,
    TREE_COMPANY: '{URL_UMS}ums/tree/getCompanyTree'  //单位树
    ,
    TREE_DEPT: '{URL_UMS}ums/tree/getDeptTree'    //部门树
    ,
    TREE_ROLE: '{URL_UMS}ums/tree/getRoleTree'    //角色树
    ,
    TREE_ROLE_CONTAINS_COMMON_ROLE: '{URL_UMS}ums/tree/getRoleTreeContainsCommonRole' //角色树含公共角色
    ,
    TREE_COMPANY_USER: '{URL_UMS}ums/tree/getCompanyUserTree' //单位用户树
    ,
    TREE_NAVIGATE: '{URL_UMS}ums/navigate/getList'    //导航树
    ,
    TREE_FS_FOLDER: '{URL_FS}fs/fileInfo/getFolderTree'    //文件夹树
    ,
    LIST_PROVINCE: '{URL_CMS}cms/administrativeRegion/getProvinceList'
    ,
    LIST_CITY_BY_PROVINCE: '{URL_CMS}cms/administrativeRegion/getCityListByProvinceCode'
    ,
    LIST_COUNTY_BY_CITY: '{URL_CMS}cms/administrativeRegion/getCountyListByCityCode'
    ,
    LIST_BUTTON_CATEGORY: '{URL_CMS}ums/button/getButtonCategoryList' //按钮分组
    ,
    LIST_BUTTON: '{URL_CMS}ums/button/getList' //按钮列表
    ,
    LIST_AUTH_BUTTON_IN_NAVIGATE: '{URL_UMS}ums/button/getButtonListInNavigate' //按钮权限-获取按钮列表
    ,
    HTML_TREE_LOADING: '<span><i class="fa fa-spinner fa-pulse fa-fw" style="font-family: FontAwesome;"></i> 正在加载...</span>' //树的正在加载html
    ,
    HTML_TREE_LOAD_FAIL: '<span style="color: red;font-weight: 700;"><i class="fa fa-frown-o fa-fw" style="font-family: FontAwesome;"></i> 加载失败！</span>' //树加载失败html
};

/**
 * 替换url常量
 * @param sUrl
 */
function replaceUrlConstants(sUrl) {
    if (!sUrl) {
        return '';
    }
    sUrl = sUrl.replace("{URL_UMS}", URL_UMS);//替换ums域名常量
    sUrl = sUrl.replace("{URL_PORTAL}", URL_PORTAL);//替换门户域名常量
    sUrl = sUrl.replace("{URL_STATIC}", URL_STATIC);//替换静态域名
    sUrl = sUrl.replace("{URL_FS}", URL_FS);//文件系统域名
    sUrl = sUrl.replace("{URL_CMS}", URL_CMS);//内容管理系统域名
    sUrl = sUrl.replace("{URL_CONFIG}", URL_CONFIG);//
    sUrl = sUrl.replace("{URL_MONITOR}", URL_MONITOR);//
    sUrl = sUrl.replace("{contextPath}", contextPath);//当前上下文地址
    sUrl = sUrl.replace("{SSO_TOKEN}", REQUEST_DATA_KEY_TOKEN + '=' + (SSO_TOKEN ? encodeURIComponent(SSO_TOKEN) : ''));//sso令牌

    //在Url后追加时间戳,防止浏览器缓存
    sUrl = sUrl + jo.getLinkSign(sUrl) + "_t=" + new Date().getTime();
    return sUrl;
}

/**
 * 加工请求数据,jo.postAjax和jo.post在发送请求前会调用此方法对传输的数据做处理
 * @param data 待处理数据
 * @param type 类型:post/postAjax
 * @return 处理后的数据
 */
function processRequestData(data, type) {
    if (typeof (data) == "object") {
        //单点参数追加
        if (!data[REQUEST_DATA_KEY_TOKEN] && SSO_TOKEN) {//不存在_token参数时且存在令牌,将sso令牌存入
            data[REQUEST_DATA_KEY_TOKEN] = SSO_TOKEN;
        }
    }
    return data;
}

/**
 * 打开页面,在首页的main窗口
 * @param sUrl 页面url
 */
function openPageOnMain(sUrl) {
    sUrl = replaceUrlConstants(sUrl);
    $("iframe[name='main']").attr("src", sUrl);
}

/*if(window != window.parent){
    progressStart();
}
$(function(){
    progressOver();
});*/
/**
 * 进度条展示
 */
function progressStart() {
    document.write('<div id="progress_core" style="width:10px;height:4px;position: fixed;top:0px;left:0px;border-radius: 2px;background-color: #242F35;border-right: #FC5743 solid 1px;"></div>');
    $("#progress_core").show();
    $("#progress_core").animate({width: '90%'});
}

/**
 * 进度条关闭
 */
function progressOver() {
    $("#progress_core").animate({width: '100%'}, "fast", function () {
        $("#progress_core").css("width", "0px");
        $("#progress_core").hide();
    });
}

/**
 * 在新窗口打开
 * @param sUrl 页面url
 */
function newWindow(sUrl) {
    jo.newWindow(sUrl);
}

/**
 * 刷新面包屑
 * @param sInfo 面包屑内容
 */
function refreshCrumbs(sInfo) {
    $("#crumbs").html(sInfo);
}

/**
 * 打开页面并且刷新面包屑
 * @param sUrl
 * @param sInfo
 */
function openPage(sUrl, sInfo) {
    openPageOnMain(sUrl);
    refreshCrumbs(sInfo);
}

/**
 * 在某个元素中展示html
 * $.html()方式
 * @param id 元素id
 * @param html html代码
 */
function showHtml(id, html) {
    $('#' + id).html(html);
}

/**
 * 创建资源菜单树
 * @param eleId 树存放的容器id,默认为navigateTree
 * @param clickFunc 树节点点击事件,参数为event,treeId,treeNode
 */
function createNavigateTree(eleId, clickFunc) {
    eleId = jo.getDefVal(eleId, "navigateTree");
    showHtml(eleId, COMMON_CONST.HTML_TREE_LOADING);//正在加载
    jo.postAjax(COMMON_CONST.TREE_NAVIGATE, {}, function (json) {
        if (json && json.code == 0) {
            var root = {//加了children后子节点中的父子关系乱掉了,之前是可以用的,有待考虑
                id: "ROOT"
                , name: "资源导航池"
                //,children:json.data
                , open: "true"
            };
            json.data.push(root);
            for (var i = 0; i < json.data.length; i++) {
                json.data[i].icon2 = json.data[i].icon;
                json.data[i].icon = null;//ztree的icon属性与资源icon字段冲突
            }
            var param = {
                treeId: eleId
                , zNodes: json.data
                , item_id: "id"
                , item_pid: "parentId"
                , item_show: "name"
            };
            if (typeof (clickFunc) == "function") {
                param.onClickFunc = clickFunc;//树节点点击回调
            }
            jo.drawZTree(param);
        } else if (json && json.code == -1) {
            jo.showMsg(jo.getDefVal(json.info, "创建资源树失败!"), {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        } else {
            jo.showMsg("创建资源树失败!", {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        }
    }, true);
}

/**
 * 创建部门树
 * @param eleId 树存放的容器id,默认为navigateTree
 * @param clickFunc 树节点点击事件,参数为event,treeId,treeNode
 */
function createDeptTree(eleId, clickFunc) {
    eleId = jo.getDefVal(eleId, "deptTree");
    showHtml(eleId, COMMON_CONST.HTML_TREE_LOADING);//正在加载
    jo.postAjax(COMMON_CONST.TREE_DEPT, {}, function (json) {
        if (json && json.code == 0) {
            /* if(json && json.data && json.data[0] && json.data[0].ID == "ROOT"){
                 json.data[0].open = true;
             }*/
            var param = {
                treeId: eleId
                , zNodes: json.data
                , item_id: "id"
                , item_pid: "parentId"
                , item_show: "name"
            };
            if (typeof (clickFunc) == "function") {
                param.onClickFunc = clickFunc;//树节点点击回调
            }
            jo.drawZTree(param);
        } else if (json && json.code == -1) {
            jo.showMsg(jo.getDefVal(json.info, "创建部门树失败!"), {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        } else {
            jo.showMsg("创建部门树失败!", {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        }
    }, true);
}

/**
 * 创建单位树
 * @param eleId
 * @param clickFunc
 */
function createCompanyTree(eleId, clickFunc) {
    eleId = jo.getDefVal(eleId, "companyTree");
    showHtml(eleId, COMMON_CONST.HTML_TREE_LOADING);//正在加载
    jo.postAjax(COMMON_CONST.TREE_COMPANY, {}, function (json) {
        if (json && json.code == 0) {
            if (json && json.data && json.data[0] && json.data[0].id == "ROOT") {
                json.data[0].open = true;
            }
            var param = {
                treeId: eleId
                , zNodes: json.data
                , item_id: "id"
                , item_pid: "parentId"
                , item_show: "name"
            };
            if (typeof (clickFunc) == "function") {
                param.onClickFunc = clickFunc;//树节点点击回调
            }
            jo.drawZTree(param);
        } else if (json && json.code == -1) {
            jo.showMsg(jo.getDefVal(json.info, "创建单位树失败!"), {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        } else {
            jo.showMsg("创建单位树失败!", {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        }
    }, true);
}

/**
 * 创建组织树
 * @param eleId
 * @param clickFunc
 */
function createOrgTree(eleId, clickFunc) {
    eleId = jo.getDefVal(eleId, "orgTree");
    showHtml(eleId, COMMON_CONST.HTML_TREE_LOADING);//正在加载
    jo.postAjax(COMMON_CONST.TREE_ORG, {}, function (json) {
        if (json && json.code == 0) {
            if (json && json.data && json.data[0] && json.data[0].id == "ROOT") {
                json.data[0].open = true;
            }
            var param = {
                treeId: eleId
                , zNodes: json.data
                , item_id: "id"
                , item_pid: "parentId"
                , item_show: "name"
            };
            if (typeof (clickFunc) == "function") {
                param.onClickFunc = clickFunc;//树节点点击回调
            }
            jo.drawZTree(param);
        } else if (json && json.code == -1) {
            jo.showMsg(jo.getDefVal(json.info, "创建组织树失败!"), {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        } else {
            jo.showMsg("创建组织树失败!", {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        }
    }, true);
}

/**
 * 创建角色树(单位-角色形式展示)
 * @param eleId 树id
 * @param clickFunc 点击事件
 * @param bChecked 是否有选择框,默认false
 */
function createRoleTree(eleId, clickFunc, bChecked) {
    eleId = jo.getDefVal(eleId, "roleTree");
    showHtml(eleId, COMMON_CONST.HTML_TREE_LOADING);//正在加载
    jo.postAjax(COMMON_CONST.TREE_ROLE, {}, function (json) {
        if (json && json.code == 0) {
            if (json && json.data && json.data[0] && json.data[0].ID == "ROOT") {
                json.data[0].open = true;
            }

            for (var i = 0; i < json.data.length; i++) {
                var n = json.data[i];
                if (n.id == 'ROOT') {
                    n.open = true;
                }
                if (n.nodeType == "DEPT") {
                    if (n.roleList && n.roleList.length > 0) {//存在角色的单位自动展开
                        n.open = true;
                    }
                    n.children = n.roleList;//角色列表以子节点的方式展示
                } else {
                    n.name = "[角色] " + n.name;
                }
                if (jo.isValid(n.children) && n.children.length > 0) {
                    for (var j = 0; j < n.children.length; j++) {
                        var n2 = n.children[j];
                        if (n2.nodeType == "DEPT") {
                            //n.open = true;
                        } else {
                            n2.name = "[角色] " + n2.name;
                        }
                    }
                }
            }

            var param = {
                treeId: eleId
                , zNodes: json.data
                , item_id: "id"
                , item_pid: "parentId"
                , item_show: "name"
            };
            if (typeof (clickFunc) == "function") {
                param.onClickFunc = clickFunc;//树节点点击回调
            }
            if (bChecked) {
                param.check = {//需引入cxcheck扩展包
                    enable: true,    //勾选框开关
                    chkStyle: "checkbox",    //默认checkbox(与chkboxType属性关联),也可以写radio(与radioType属性关联)
                    chkboxType: {"Y": "ps", "N": "s"},    //Y和N固定不变,Y表示勾选,N表示取消勾选;Y和N的值为p或s或ps,p表示会影响父节点,s表示会影响子节点
                    radioType: "all"    //取值为"all"和"level",all表示在所有节点中单选,level表示在同一层级内单选
                };
            }
            jo.drawZTree(param);
        } else if (json && json.code == -1) {
            jo.showMsg(jo.getDefVal(json.info, "创建角色树失败!"), {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        } else {
            jo.showMsg("创建角色树失败!", {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        }
    }, true);
}

/**
 * 创建包含共享角色的角色树(单位-角色形式展示)
 * @param eleId 树id
 * @param clickFunc 点击事件
 * @param bChecked 是否有选择框,默认false
 */
function createRoleTreeContainsCommonRole(eleId, clickFunc, bChecked) {
    eleId = jo.getDefVal(eleId, "roleTree");
    showHtml(eleId, COMMON_CONST.HTML_TREE_LOADING);//正在加载
    jo.postAjax(COMMON_CONST.TREE_ROLE_CONTAINS_COMMON_ROLE, {}, function (json) {
        if (json && json.code == 0) {
            if (json && json.data && json.data[0] && json.data[0].ID == "ROOT") {
                json.data[0].open = true;
            }

            for (var i = 0; i < json.data.length; i++) {
                var n = json.data[i];
                if (n.id == 'ROOT') {
                    n.open = true;
                }
                if (n.nodeType == "DEPT") {
                    if (n.roleList && n.roleList.length > 0) {//存在角色的单位自动展开
                        n.open = true;
                    }
                    n.children = n.roleList;//角色列表以子节点的方式展示
                } else {
                    n.name = "[角色] " + n.name;
                }
                if (jo.isValid(n.children) && n.children.length > 0) {
                    for (var j = 0; j < n.children.length; j++) {
                        var n2 = n.children[j];
                        if (n2.nodeType == "DEPT") {
                            //n.open = true;
                        } else {
                            n2.name = "[角色] " + n2.name;
                        }
                    }
                }
            }

            var param = {
                treeId: eleId
                , zNodes: json.data
                , item_id: "id"
                , item_pid: "parentId"
                , item_show: "name"
            };
            if (typeof (clickFunc) == "function") {
                param.onClickFunc = clickFunc;//树节点点击回调
            }
            if (bChecked) {
                param.check = {//需引入cxcheck扩展包
                    enable: true,    //勾选框开关
                    chkStyle: "checkbox",    //默认checkbox(与chkboxType属性关联),也可以写radio(与radioType属性关联)
                    chkboxType: {"Y": "ps", "N": "s"},    //Y和N固定不变,Y表示勾选,N表示取消勾选;Y和N的值为p或s或ps,p表示会影响父节点,s表示会影响子节点
                    radioType: "all"    //取值为"all"和"level",all表示在所有节点中单选,level表示在同一层级内单选
                };
            }
            jo.drawZTree(param);
        } else if (json && json.code == -1) {
            jo.showMsg(jo.getDefVal(json.info, "创建角色树失败!"), {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        } else {
            jo.showMsg("创建角色树失败!", {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        }
    }, true);
}

/**
 * 创建单位用户树
 * @param eleId 树容器id
 * @param clickFunc 树点击时间
 * @param bChecked 是否可选
 */
function createCompanyUserTree(eleId, clickFunc, bChecked) {
    eleId = jo.getDefVal(eleId, "companyUserTree");
    showHtml(eleId, COMMON_CONST.HTML_TREE_LOADING);//正在加载
    jo.postAjax(COMMON_CONST.TREE_COMPANY_USER, {}, function (json) {
        if (json && json.code == 0) {
            if (json && json.data && json.data[0] && json.data[0].ID == "ROOT") {
                json.data[0].open = true;
            }

            for (var i = 0; i < json.data.length; i++) {
                var n = json.data[i];
                if (n.id == 'ROOT') {
                    n.open = true;
                }
                if (n.nodeType == "DEPT") {
                    n.children = n.userList;//角色列表以子节点的方式展示
                } else {
                    n.name = "[用户] " + n.name;
                }
                if (jo.isValid(n.children) && n.children.length > 0) {
                    for (var j = 0; j < n.children.length; j++) {
                        var n2 = n.children[j];
                        if (n2.nodeType == "DEPT") {

                        } else {
                            n2.name = "[用户] " + n2.name;
                        }
                    }
                }
            }

            var param = {
                treeId: eleId
                , zNodes: json.data
                , item_id: "id"
                , item_pid: "parentId"
                , item_show: "name"
            };
            if (typeof (clickFunc) == "function") {
                param.onClickFunc = clickFunc;//树节点点击回调
            }
            if (bChecked) {
                param.check = {//需引入cxcheck扩展包
                    enable: true,    //勾选框开关
                    chkStyle: "checkbox",    //默认checkbox(与chkboxType属性关联),也可以写radio(与radioType属性关联)
                    chkboxType: {"Y": "ps", "N": "s"},    //Y和N固定不变,Y表示勾选,N表示取消勾选;Y和N的值为p或s或ps,p表示会影响父节点,s表示会影响子节点
                    radioType: "all"    //取值为"all"和"level",all表示在所有节点中单选,level表示在同一层级内单选
                };
            }
            jo.drawZTree(param);
        } else if (json && json.code == -1) {
            jo.showMsg(jo.getDefVal(json.info, "创建单位用户树失败!"), {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        } else {
            jo.showMsg("创建单位用户树失败!", {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        }
    }, true);
}

/**
 * 创建文件夹树
 * @param eleId
 * @param clickFunc
 */
function createFolderTree(eleId, clickFunc) {
    eleId = jo.getDefVal(eleId, "folderTree");
    showHtml(eleId, COMMON_CONST.HTML_TREE_LOADING);//正在加载
    jo.postAjax(COMMON_CONST.TREE_FS_FOLDER, {}, function (json) {
        if (json && json.code == 0) {
            if (json && json.data && json.data[0] && json.data[0].id == "ROOT") {
                json.data[0].open = true;
            }
            var param = {
                treeId: eleId
                , zNodes: json.data
                , item_id: "id"
                , item_pid: "folderId"
                , item_show: "name"
            };
            if (typeof (clickFunc) == "function") {
                param.onClickFunc = clickFunc;//树节点点击回调
            }
            jo.drawZTree(param);
        } else if (json && json.code == -1) {
            jo.showMsg(jo.getDefVal(json.info, "创建文件夹树失败!"), {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        } else {
            jo.showMsg("创建文件夹树失败!", {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        }
    });
}

/**
 * 创建可编辑的文件夹树
 * @param eleId
 * @param clickFunc
 */
function createEditableFolderTree(eleId, clickFunc) {
    eleId = jo.getDefVal(eleId, "folderTree");
    showHtml(eleId, COMMON_CONST.HTML_TREE_LOADING);//正在加载
    jo.postAjax(COMMON_CONST.TREE_FS_FOLDER, {}, function (json) {
        if (json && json.code == 0) {
            if (json && json.data && json.data[0] && json.data[0].id == "ROOT") {
                json.data[0].open = true;
            }
            var param = {
                treeId: eleId
                , zNodes: json.data
                , item_id: "id"
                , item_pid: "folderId"
                , item_show: "name"
            };
            if (typeof (clickFunc) == "function") {
                param.onClickFunc = clickFunc;//树节点点击回调
            }
            param.edit = {
                enable: true,
                removeTitle: "删除",
                renameTitle: "编辑",
                showRemoveBtn: true,
                showRenameBtn: false
            };
            //初始化树的前置处理
            param.initZTreeBefore = function (sTreeId, setting, nodes) {
                //删除节点前的回调
                setting.callback.beforeRemove = function (treeId, treeNode) {
                    var res = false;
                    if (treeNode.id) {
                        if (treeNode.id == "ROOT") {
                            jo.alert("不允许删除根目录!");
                            return false;
                        }
                        if (window.confirm("您确定要删除此文件夹及此文件夹下所有文件?")) {
                            jo.postAjax("{URL_FS}fs/file/dropFolder", {folderId: treeNode.id}, function (json) {
                                if (json && json.code == "0") {
                                    res = true;
                                    jo.showMsg("文件夹删除成功!");
                                }
                            });
                        }
                    }
                    return res;
                };
                //添加新增按钮
                setting.view.addHoverDom = function (treeId, treeNode) {
                    var sObj = $("#" + treeNode.tId + "_span"); //获取节点信息
                    if (treeNode.editNameFlag || $("#addBtn_" + treeNode.tId).length > 0) return;

                    var addStr = "<span class='button add' id='addBtn_" + treeNode.tId + "' title='新建子文件夹' onfocus='this.blur();'></span>"; //定义添加按钮
                    sObj.after(addStr); //加载添加按钮
                    var btn = $("#addBtn_" + treeNode.tId);

                    //绑定添加事件，并定义添加操作
                    if (btn) btn.bind("click", function () {
                        var zTree = $.fn.zTree.getZTreeObj("folderTree");
                        //将新节点添加到数据库中
                        jo.prompt({maxlength: 10, title: "新建文件夹名称"}, function (value, index, elem) {
                            var name = value;
                            jo.postAjax("{URL_FS}fs/file/createFolder", {
                                "name": name,
                                "folderId": treeNode.id
                            }, function (json) {
                                if (json && json.code == "0") {
                                    var newNode = json.data[0]; //获取新添加的节点Id
                                    zTree.addNodes(treeNode, {"id": newNode.id, "folderId": treeNode.id, "name": name}); //页面上添加节点
                                    var node = zTree.getNodeByParam("id", newNode.id, null); //根据新的id找到新添加的节点
                                    zTree.selectNode(node); //让新添加的节点处于选中状态
                                    jo.close(index);
                                    if (joView.inited) {
                                        joView.reloadCurrentPage();//刷新当前页信息展示
                                    }
                                }
                            });
                        });
                    });
                };
                setting.view.removeHoverDom = function (treeId, treeNode) {
                    $("#addBtn_" + treeNode.tId).unbind().remove();
                };
            };
            jo.drawZTree(param);
        } else if (json && json.code == -1) {
            jo.showMsg(jo.getDefVal(json.info, "创建文件夹树失败!"), {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        } else {
            jo.showMsg("创建文件夹树失败!", {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        }
    });
}

/**
 * 创建按钮分类列表
 * @param eleId
 * @param clickFunc
 */
function createButtonCategoryList(eleId, clickFunc) {
    eleId = jo.getDefVal(eleId, "buttonCategoryTree");
    showHtml(eleId, COMMON_CONST.HTML_TREE_LOADING);//正在加载
    jo.postAjax(COMMON_CONST.LIST_BUTTON_CATEGORY, {}, function (json) {
        if (json && json.code == 0) {
            for (var i = 0; i < json.data.length; i++) {
                json.data[i] = {name: json.data[i]};
            }

            var param = {
                treeId: eleId
                , zNodes: {id: 'ROOT', name: '按钮分组', open: true, children: json.data}
                , item_id: "id"
                , item_pid: "parentId"
                , item_show: "name"
            };
            if (typeof (clickFunc) == "function") {
                param.onClickFunc = clickFunc;//树节点点击回调
            }
            jo.drawZTree(param);
        } else if (json && json.code == -1) {
            jo.showMsg(jo.getDefVal(json.info, "创建按钮分类列表失败!"), {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        } else {
            jo.showMsg("创建按钮分类列表失败!", {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        }
    });
}

/**
 * 创建按钮树
 * @param eleId
 * @param clickFunc
 * @param bChecked 是否可选
 */
function createButtonTree(eleId, clickFunc, bChecked) {
    eleId = jo.getDefVal(eleId, "buttonTree");
    showHtml(eleId, COMMON_CONST.HTML_TREE_LOADING);//正在加载
    jo.postAjax(COMMON_CONST.LIST_BUTTON, {}, function (json) {
        if (json && json.code == 0) {
            var obj = {};
            for (var i = 0; i < json.data.length; i++) {
                var item = json.data[i];
                //item.nodeType = 'BUTTON';//节点类型,用来区分按钮和分组节点
                item.icon2 = item.icon;
                item.icon = '';
                if (!obj[item.category]) {//不存在这个分组
                    obj[item.category] = [];
                }
                obj[item.category].push(item);
            }
            var arr = [];
            for (var k in obj) {
                arr.push({id: k, name: k, category: 'ROOT', children: obj[k]});
            }
            var param = {
                treeId: eleId
                , zNodes: arr
                , item_id: "id"
                , item_pid: "category"
                , item_show: "name"
            };
            if (typeof (clickFunc) == "function") {
                param.onClickFunc = clickFunc;//树节点点击回调
            }
            if (bChecked) {
                param.check = {//需引入cxcheck扩展包
                    enable: true,    //勾选框开关
                    chkStyle: "checkbox",    //默认checkbox(与chkboxType属性关联),也可以写radio(与radioType属性关联)
                    chkboxType: {"Y": "ps", "N": "s"},    //Y和N固定不变,Y表示勾选,N表示取消勾选;Y和N的值为p或s或ps,p表示会影响父节点,s表示会影响子节点
                    radioType: "all"    //取值为"all"和"level",all表示在所有节点中单选,level表示在同一层级内单选
                };
            }
            jo.drawZTree(param);
        } else if (json && json.code == -1) {
            jo.showMsg(jo.getDefVal(json.info, "创建按钮树失败!"), {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        } else {
            jo.showMsg("创建按钮树失败!", {icon: 2});
            showHtml(eleId, COMMON_CONST.HTML_TREE_LOAD_FAIL);//加载失败
        }
    });
}

/**
 * 选择资源菜单
 * 用于表单中的资源输入
 * @param idInp 回填id的输入框id
 * @param nameInp 回填name的输入框id
 * @param bMore 是否允许多选,默认单选
 */
function choiceNavigate(idInp, nameInp, bMore) {
    jo.selectTree(COMMON_CONST.TREE_NAVIGATE, jo.getDefVal(idInp, 'parentId'), jo.getDefVal(nameInp, 'parentName'), 'id', 'name', 'parentId', bMore, null, {
        drawBeforeCallBack: function (zNodes) {
            zNodes.push({
                id: "ROOT"
                , name: "ROOT"
                , open: "true"
            });
            for (var i = 0; i < zNodes.length; i++) {
                zNodes[i].icon2 = zNodes[i].icon;
                zNodes[i].icon = null;//ztree的icon属性与资源icon字段冲突
            }
        }
    });
}

/**
 * 选择部门,仅部门
 * @param idInp 回填id的输入框id
 * @param nameInp 回填name的输入框id
 * @param bMore 是否允许多选,默认单选
 */
function choiceDept(idInp, nameInp, bMore) {
    jo.selectTree(COMMON_CONST.TREE_DEPT, jo.getDefVal(idInp, 'parentId'), jo.getDefVal(nameInp, 'parentName'), 'id', 'name', 'parentId', bMore);
}

/**
 * 选择单位
 * @param idInp 回填id的输入框id
 * @param nameInp 回填name的输入框id
 * @param bMore 是否允许多选,默认单选
 * @param rootId 单位树根节点,可以为空,默认查询用户权限范围内的单位树
 * @param callback 回调函数(yesOrNo, ids, names)
 * @param selectTreeId 树选择组件id,一个页面存在多个树选择时必须指定
 */
function choiceCompany(idInp, nameInp, bMore, rootId, callback, selectTreeId) {
    var url = COMMON_CONST.TREE_COMPANY;
    if (rootId) {
        url += jo.getLinkSign(url) + 'rootId=' + rootId;
    }
    var treeId = jo.getDefVal(selectTreeId, 'choiceCompanyTree');
    // jo.selectTree(url, jo.getDefVal(idInp, 'parentId'), jo.getDefVal(nameInp, 'parentName'), 'id','name', 'parentId', bMore, callback, {id:selectTreeId});
    jo.selectTree({
        id: treeId
        , url: url
        , inp_id: jo.getDefVal(idInp, 'parentId')
        , inp_text: jo.getDefVal(nameInp, 'parentName')
        , field_id: 'id'
        , field_text: 'name'
        , field_pid: 'parentId'
        , multiple: bMore
        , selectListCall: callback
        , drawBeforeCallBack: function (list, id) {
            if (id == treeId) {
                if (list && list[0] && list[0].id == "ROOT") {
                    list[0].open = true;
                }
            }
        }
    });
}

/**
 * 选择组织,不区分单位和部门
 * @param idInp 回填id的输入框id
 * @param nameInp 回填name的输入框id
 * @param bMore 是否允许多选,默认单选
 */
function choiceOrg(idInp, nameInp, bMore) {
    jo.selectTree(COMMON_CONST.TREE_ORG, jo.getDefVal(idInp, 'parentId'), jo.getDefVal(nameInp, 'parentName'), 'id', 'name', 'parentId', bMore);
}

/**
 * 选择角色(含上级公开角色)
 * @param idInp 回填id的输入框id
 * @param nameInp 回填name的输入框id
 * @param bMore 是否允许多选,默认单选
 * @param selectTreeId 树id
 * @param callback 回调函数(yesOrNo, ids, names)
 */
function choiceRoleContainsCommonRole(idInp, nameInp, bMore, selectTreeId, callback) {
    var treeId = jo.getDefVal(selectTreeId, 'choiceRole');
    jo.selectTree({
        id: treeId
        , url: COMMON_CONST.TREE_ROLE_CONTAINS_COMMON_ROLE
        , inp_id: jo.getDefVal(idInp, 'roleId')
        , inp_text: jo.getDefVal(nameInp, 'roleName')
        , field_id: 'id'
        , field_text: 'name'
        , field_pid: 'parentId'
        , multiple: bMore
        , selectListCall: callback
        , drawBeforeCallBack: function (list, id) {
            if (id == treeId) {
                if (list && list[0] && list[0].ID == "ROOT") {
                    list[0].open = true;
                }

                for (var i = 0; i < list.length; i++) {
                    var n = list[i];
                    if (n.id == 'ROOT') {
                        n.open = true;
                    }
                    if (n.nodeType == "DEPT") {
                        if (n.roleList && n.roleList.length > 0) {//存在角色的单位自动展开
                            n.open = true;
                        }
                        n.children = n.roleList;//角色列表以子节点的方式展示
                    } else {
                        n.name = "[角色] " + n.name;
                    }
                    if (jo.isValid(n.children) && n.children.length > 0) {
                        for (var j = 0; j < n.children.length; j++) {
                            var n2 = n.children[j];
                            if (n2.nodeType == "DEPT") {
                                //n.open = true;
                            } else {
                                n2.name = "[角色] " + n2.name;
                            }
                        }
                    }
                }
            }
        }
        , nodeCanChoiceCallBack: function (treeNode) {
            if (treeNode.nodeType == "ROLE") {//节点类型为角色则允许选择
                return true;
            }
            return false;
        }
    });
}

/**
 * 选择图标
 * @param inpId 回显图标class的输入框id
 * @param callback 回掉函数,参数为被选中图标的class
 */
function choiceIcon(inpId, callback) {
    jo.selectIcon(jo.getDefVal(inpId, "icon"), callback);
}

/**
 * 下载文件
 * @param fileId 文件编号
 */
function downloadFile(fileId) {
    if (jo.isValid(fileId)) {
        jo.confirm("您确定要下载该文件吗?", {title: "下载确认"}, function (idx) {
            jo.post("{URL_FS}fs/file/download", {"fileId": fileId});
            jo.close(idx);
        });
    } else {
        console.error("文件编号无效,无法下载!");
    }
}

/**
 * 删除文件
 * @param fileId 文件编号
 */
function dropFile(fileId) {
    if (jo.isValid(fileId)) {
        jo.confirm("您确定要删除该文件吗?", {title: "删除确认"}, function () {
            jo.postAjax("{URL_FS}fs/file/dropFile", {"fileId": fileId}, function (json) {
                if (json && json.code == "0") {
                    jo.showMsg("成功删除文件!");
                    if (joView.inited) {
                        joView.reloadCurrentPage();
                    }
                }
                if (json && json.code == "-1") {
                    jo.showMsg(json.info);
                }
            });
        });
    } else {
        console.error("文件编号无效,无法删除!");
    }
}

/**
 * 预览文件
 * @param fileId
 */
function previewFile(fileId) {
    if (jo.isValid(fileId)) {
        jo.newWindow("{URL_FS}fs/file/preview/" + fileId);
    } else {
        console.error("文件编号无效,无法预览!");
    }
}

/**
 * 初始化省市县联动
 * @param province 省份下拉框的id
 * @param city 市下拉框的id
 * @param county 县下拉框的id
 * @param proVal 省份初值,没有则不填
 * @param cityVal 市初值,没有则不填
 * @param countyVal 县初值,没有则不填
 * @param proUrl 省份列表url,默认使用常量:COMMON_CONST.LIST_PROVINCE
 */
function initProvinceCityCounty(province, city, county, proVal, cityVal, countyVal, proUrl) {
    var proSelect = JoSelectTool[province];
    var citySelect = JoSelectTool[city];
    var countySelect = JoSelectTool[county];
    window.ProvinceCityCountyInitVal = [proVal, cityVal, countyVal];
    var choiceProCall = function (ele) {
        //省变化,清空市,同时也清空县
        citySelect.clear();
        countySelect.clear();
        if (ele.value) {
            jo.postAjax(COMMON_CONST.LIST_CITY_BY_PROVINCE, {"provinceCode": ele.value}, function (json) {
                if (json && json.code == "0") {
                    citySelect.load(json.data);
                }
            }, true);
        }
    };
    var choiceCityCall = function (ele) {
        //市变化,清空县
        countySelect.clear();
        if (ele.value) {
            jo.postAjax(COMMON_CONST.LIST_COUNTY_BY_CITY, {"cityCode": ele.value}, function (json) {
                if (json && json.code == "0") {
                    countySelect.load(json.data);
                }
            }, true);
        }
    };
    //加载完成事件
    proSelect.on('loaded', function () {
        if (window.ProvinceCityCountyInitVal[0]) {
            console.info(window.ProvinceCityCountyInitVal[0])
            proSelect.setValue(window.ProvinceCityCountyInitVal[0]);
            window.ProvinceCityCountyInitVal[0] = null;
            choiceProCall(proSelect.element);
        }
    });
    citySelect.on('loaded', function () {
        if (window.ProvinceCityCountyInitVal[1]) {
            citySelect.setValue(window.ProvinceCityCountyInitVal[1]);
            window.ProvinceCityCountyInitVal[1] = null;
            choiceCityCall(citySelect.element);
        }
    });
    countySelect.on('loaded', function () {
        if (window.ProvinceCityCountyInitVal[2]) {
            countySelect.setValue(window.ProvinceCityCountyInitVal[2]);
            window.ProvinceCityCountyInitVal[2] = null;
        }
    });
    //选择事件
    $("#" + province).bind('change', function () {
        choiceProCall(this);
    });
    $("#" + city).bind('change', function () {
        choiceCityCall(this);
    });
    $("#" + county).bind('change', function () {

    });
    jo.postAjax(proUrl || COMMON_CONST.LIST_PROVINCE, {}, function (json) {
        if (json && json.code == "0") {
            proSelect.load(json.data);
        }
    }, true);
}

/**
 * 格式化状态显示内容
 * @param state 状态,1/0
 * @returns {*}
 */
function formatYesOrNo(state) {
    if (state == '1') {
        return '<span class="label label-success">是</span>';
    } else if (state == '0') {
        return '<span class="label label-danger">否</span>';
    } else {
        return state;
    }
}

/**
 * 格式化行政区划等级
 * @param level 等级编码
 * @returns {*}
 */
function formatAdministrativeRegionLevel(level) {
    if (level == '1') {
        return '<span class="label label-primary">省</span>';
    } else if (level == '2') {
        return '<span class="label label-info">市</span>';
    } else if (level == '3') {
        return '<span class="label label-warning">县</span>';
    } else {
        return level;
    }
}

/**
 * 初始化按钮,从服务端拉取资源下的按钮(权限控制)
 */
function initButton() {
    $('.young-button-placeholder').each(function (idx, ele) {
        var navId = $(ele).attr('navigateId');//资源编号
        if (navId) {
            jo.postAjax(COMMON_CONST.LIST_AUTH_BUTTON_IN_NAVIGATE, {navigateId: navId}, function (json) {
                if (json && json.code == 0) {
                    var btnArr = json.data;//按钮数组
                    if (btnArr && btnArr.length > 0) {
                        var _html = '';
                        for (var i = 0; i < btnArr.length; i++) {
                            var btn = btnArr[i];
                            try {
                                //验证显示条件,验证失败则不渲染此按钮
                                if (btn.display) {
                                    var res = jo.execCode(btn.display);
                                    if (res == false || res == 'false' || res === 0) {
                                        console.info(btn.name + ' -- ' + res);
                                        continue;
                                    }
                                }
                            } catch (err) {
                                console.info('解析按钮显示条件异常:' + btn.name);
                                console.error(err);
                            }
                            //按钮信息解析为按钮html
                            if (typeof (parseButton2Html) == 'function') {
                                _html += parseButton2Html(btn);
                            } else {
                                _html += ' <button type="button" class="' + btn.buttonClass + '" onclick=' + btn.click + '><i class="fa ' + btn.icon + '"></i>&nbsp;' + btn.name + '</button>';// isShow="'+btn.display+'"
                            }
                        }
                        $(ele).html(_html);
                    }
                }
            }, true);
        }
    });
}

/**
 * 更多搜索条件展开/收起
 * @param btn 按钮本身,传this
 * @param moreId 要显示的按钮组id
 */
function moreSearchCondition(btn, moreId) {
    $('#' + moreId).toggle();
    $(btn).toggleClass('btn-search-more-open');
    $(btn).toggleClass('btn-search-more-close');
}

/**
 * 将内容包装为label展示
 * @param val 值
 * @param style 样式,label-primary,label-info,label-success,label-warning,label-danger,label-default
 * @param clickFunc 点击事件
 * @returns {string}
 */
function htmlWrap4Label(val, style, clickFunc) {
    if (clickFunc) {
        clickFunc = clickFunc.replace(/\"/ig, '&quot;').replace(/\'/ig, '&#x27;');
    }
    return '<span class="label' + (clickFunc ? ' cursor-hand' : '') + ' ' + jo.getDefVal(style, 'label-default') + '" '
        + (clickFunc ? (' onclick="' + clickFunc + '"') : '')
        + '>' + val + '</span>';
}

/**
 * 按钮html
 * @param param 具体参数看代码
 * @returns {string}
 */
function htmlWrap4Button(param) {
    var btnTemp = '<button type="button" class="btn ${class}" onclick="${click}"><i class="fa ${icon}" aria-hidden="true"></i>&nbsp;${val}</button>';
    var clickPart = param.click ? param.click.replace(/\"/ig, '&quot;').replace(/\'/ig, '&#x27;') : '';
    return btnTemp
        .replace('${class}', jo.getDefVal(param.class, 'btn-primary'))
        .replace('${click}', jo.getDefVal(clickPart, ''))
        .replace('${icon}', jo.getDefVal(param.icon, 'fa-plus'))
        .replace('${val}', jo.getDefVal(param.val, '--'))
        ;
    // return '<button type="button" class="btn '+param.class+'" '+clickPart+'><i class="fa fa-trash-o" aria-hidden="true"></i>&nbsp;'+param.val+'</button>';
}

/**
 * 枚举类获取枚举数组
 * @returns {*[]}
 */
function enumItems() {
    var arr = [];
    for (var k in this) {
        if (typeof this[k] == 'function') {
            continue;
        }
        arr.push(this[k]);
    }
    return arr;
}
//枚举值生成label
function enumLabelHtml(id) {
    var item = this.of(id);
    if (item.id) {
        return htmlWrap4Label(item.name, item.label);
    }
    return htmlWrap4Label(id);
}
/**
 * 枚举类根据id匹配枚举值
 * @param id
 * @returns {{}|*}
 */
function enumOf(id) {
    var arr = this.items();
    for (var i = 0; i < arr.length; i++) {
        var item = arr[i];
        if (item.id == id) {
            return item;
        }
    }
    return {};
}
// 枚举声明举例, 注意items和of要有
const TEST_ENUM = {
    ON: {id: 1, name: '上线'}
    , items: enumItems
    , of: enumOf
};